#include "ComponentFactory.h"

using namespace std;




ComponentFactory* ComponentFactory::ms_instance = 0;
//std::map<std::string, ComponentFactory::ComponentCreator>* ComponentFactory::creators;
//ComponentCreatorMap ComponentFactory::creators = ComponentCreatorMap();


ComponentFactory::ComponentFactory()
{
	creators = new ComponentCreatorMap();
}

ComponentFactory::~ComponentFactory()
{
	delete creators;
	creators = 0;
}

ComponentFactory* ComponentFactory::getSingletonPtr()
{
	if(ms_instance == 0)
		{
			ms_instance = new ComponentFactory();
		}
	return ms_instance;
}

ComponentFactory& ComponentFactory::getSingleton()
{
	if(ms_instance == 0)
		{
			ms_instance = new ComponentFactory();
		}
	return *ms_instance;
}

void ComponentFactory::Release()
{
	delete ms_instance;
	ms_instance = 0;
}


void ComponentFactory::Register(const std::string& type, IComponentCreator* functor)
{
	if(creators == 0)
		creators = new ComponentCreatorMap();

	if(creators->empty() || creators->find(type) == creators->end())
		{
			std::pair<std::string, IComponentCreator*> value(type, functor);
			creators->insert(value);
		}
}

Component* ComponentFactory::Create(ComponentContainer* owner, const std::string& compType, const std::string& compName)
{
	if(creators == 0 || creators->empty())
		return 0;

	ComponentCreatorMap::iterator it = creators->find(compType);
	if(it == creators->end())
		{
			throw ComponentFactoryException("Unable to locate creator for component type '" + compType + "'");
			return 0;
		}

	IComponentCreator* creator = it->second;

	if(compName.empty())
		return (*creator)(owner, compType);
	else
		return (*creator)(owner, compName);
}
